package com.month.security.service.ipml;

import com.month.security.dto.response.LoginUser;
import com.month.security.entity.SysUser;
import com.month.security.service.SysUserService;
import com.month.security.utils.IdUtils;
import com.month.security.utils.StringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * jwt服务
 */
@Component
@Slf4j
public class JwtService {


    /**
     * 系统密钥
     */
    @Value("${token.secret}")
    private String secret;

    private static final String TOKEN_HEADER = "Authorization"; //请求头名称
    private static final String TOKEN_PREFIX = "Bearer "; //令牌前缀


    @Autowired
    SysUserService sysUserService;


    /**
     * 调用登录成功后生成token
     * @param loginUser
     * @return
     */
    public String createToken(LoginUser loginUser) {
        String token = IdUtils.fastUUID(); //用于缓存中的键值
        loginUser.setToken(token);
        Map<String, Object> claims = new HashMap<>();
        claims.put("userName",loginUser.getUsername());
        claims.put("token",token);
        return createToken(claims);
    }


    /**
     * 获取用户信息
     * @param request
     * @return
     */
    public LoginUser getLoginUser(HttpServletRequest request) {
        String token = getToken(request);
        if(StringUtils.isNotEmpty(token)){
            Set<String> permissions= new HashSet<>();
            try {
                //解析令牌
                Claims claims = parseToken(token);
                String userName = (String) claims.get("userName");
                //从数据库中获取用户信息
                SysUser sysUser = sysUserService.selectUserByUserName(userName);
                //设置用户权限
                if(sysUser.getUsername().equals("admin")){
                    permissions.add("R1");
                }

                if(sysUser.getUsername().equals("2003")){
                    permissions.add("R2");
                }
                return new LoginUser(sysUser, permissions);
            }catch (Exception e){
                log.error("获取用户信息异常'{}'", e.getMessage());
            }
        }
        return null;
    }


    /**
     * 从数据声明生成令牌--内部使用
     * @param claims
     * @return
     */
    private String createToken(Map<String, Object> claims) {
        return  Jwts.builder()
                .setClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
                .signWith(getKey())
                .compact();
    }

    /**
     * 解析令牌
     * @param token
     * @return
     */

    private Claims parseToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }


    /**
     * 加载密钥
     * @return
     */
    private SecretKey getKey(){
        return Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
    }


    /**
     * 获取从请求中token令牌
     * @param request
     * @return
     */
    private String  getToken(HttpServletRequest request){
        String header = request.getHeader(TOKEN_HEADER);
        if (header != null && header.startsWith(TOKEN_PREFIX)){
            return header.replace(TOKEN_PREFIX,"");
        }
        return header;
    }


}
